//
//  SCIAPManager.m
//  SCSoundCommunity
//
//  Created by  on 2023/3/28.
//  Copyright © 2023 scTeam. All rights reserved.
//

#import "SCIAPManager.h"
static NSString * const receiptKey = @"receipt_key";
static NSString * const dateKey = @"date_key";
static NSString * const userIdKey = @"userId_key";
static NSString * const orderNoKey = @"orderNo_Key";
static NSString * const transactionIdentifierKey = @"transactionIdentifier_Key";

dispatch_queue_t iap_queue() {
    static dispatch_queue_t as_iap_queue;
    static dispatch_once_t onceToken_iap_queue;
    dispatch_once(&onceToken_iap_queue, ^{
        as_iap_queue = dispatch_queue_create("com.iap.queue", DISPATCH_QUEUE_CONCURRENT);
    });
    
    return as_iap_queue;
}
@interface SCIAPManager ()<SKPaymentTransactionObserver, SKProductsRequestDelegate>


@property (nonatomic, copy) NSString *receipt; //交易成功后拿到的一个64编码字符串

@property (nonatomic, copy) NSString *transactionIdentifier;  //交易流水号

@property (nonatomic, copy) NSString *orderNo; //服务生成的订单号

@property (nonatomic, copy) NSString *date; //交易时间

@property (nonatomic, copy) NSString *userId; //交易人

@property (nonatomic, copy) NSString *productId;

@property (nonatomic,strong)NSNumber *price;


@end

@implementation SCIAPManager

+ (SCIAPManager *)sharedManager {
    static SCIAPManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

- (void)startManager { //开启监听
    
    dispatch_async(iap_queue(), ^{
                
        /***
         内购支付两个阶段：
         1.app直接向苹果服务器请求商品，支付阶段；
         2.苹果服务器返回凭证，app向公司服务器发送验证，公司再向苹果服务器验证阶段；
         */
        
        /**
         阶段一正在进中,app退出。
         在程序启动时，设置监听，监听是否有未完成订单，有的话恢复订单。
         */
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

        
    });
}


- (void)stopManager{
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    });
}


#pragma mark 查询
- (void)requestProductWithId:(NSString *)productId orderNo:(NSString *)orderNo price:(NSNumber *)price{
    
    self.orderNo = orderNo;
    self.productId = productId;
    self.price = price;
   
    if ([SKPaymentQueue canMakePayments]) { //用户允许app内购
        
        if (productId.length) {
            [ASHUD showASLoading];
            NSArray *product = [[NSArray alloc] initWithObjects:productId, nil];
            NSSet *set = [NSSet setWithArray:product];
            SKProductsRequest *productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
            productRequest.delegate = self;
            [productRequest start];
        } else {
//            NSLog(@"商品为空");
            [self filedWithErrorCode:IAP_FILEDCOED_EMPTYGOODS error:nil];
        }
        
    } else { //没有权限
        
        [self filedWithErrorCode:IAP_FILEDCOED_NORIGHT error:nil];
    }

}


#pragma mark SKProductsRequestDelegate 查询成功后的回调
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    
    NSArray *product = response.products;
    if (product.count == 0) {
//        NSLog(@"无法获取商品信息，请重试");
        dispatch_async(dispatch_get_main_queue(), ^{
            [ASHUD hideHUD];
        });
        [self filedWithErrorCode:IAP_FILEDCOED_CANNOTGETINFORMATION error:nil];
    } else {
        //发起购买请求
        SKPayment *payment = [SKPayment paymentWithProduct:product[0]];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
        
}


#pragma mark SKProductsRequestDelegate 查询失败后的回调
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    [self filedWithErrorCode:IAP_FILEDCOED_APPLECODE error:[error localizedDescription]];
}


#pragma Mark 购买操作后的回调
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions {
    
    for (SKPaymentTransaction *transaction in transactions) {
        
        switch (transaction.transactionState) {
                
            case SKPaymentTransactionStatePurchasing://正在交易
                
                break;
                
            case SKPaymentTransactionStatePurchased://交易完成
                [ASHUD hideHUD];
                self.transactionIdentifier = transaction.transactionIdentifier;
                                
                [self postData];
                
                [self completeTransaction:transaction];
                
                break;
                
            case SKPaymentTransactionStateFailed://交易失败

                [ASHUD hideHUD];
                [self failedTransaction:transaction];
                
                break;
                
            case SKPaymentTransactionStateRestored://已经购买过该商品

                [ASHUD hideHUD];
                [self restoreTransaction:transaction];
                
                break;
                
            default:
                
                break;
        }
    }
}

- (void)postData{
    //校验订单前打点
    if (!self.code){return;}
    [ASHUD showASLoading];
    //获取交易成功后的购买凭证
    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    self.receipt = [receiptData base64EncodedStringWithOptions:0];
    
    [[BJNetManager shareNetManager] postPaymentWithOrderNo:self.orderNo payload:self.receipt transactionId:self.transactionIdentifier completionHandler:^(id  _Nonnull responOj, NSError * _Nonnull error) {
        if (!error){
            [ASHUD hideHUD];
            NSDictionary *dict = responOj;
            NSInteger code = [dict[@"code"] integerValue];
            if (code == 0){
                BOOL data = dict[@"data"];
                if (data) {
                    [[NSNotificationCenter defaultCenter]postNotificationName:kNotificationAppleSuccessfulPurchase object:nil];
                }
            }else{
                NSString *msg = dict[@"msg"];
                [ASHUD showWithText:msg afterDelay:1];
            }
            [self paySuccessWithResult:dict[@"msg"] resultCode:code];
        }else{
            [ASHUD showWithText:@"payment error" afterDelay:1];
        }

    }];
}


- (void)completeTransaction:(SKPaymentTransaction *)transaction {
        
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}


- (void)failedTransaction:(SKPaymentTransaction *)transaction {
    
    NSLog(@"transaction.error.code = %ld", transaction.error.code);
    
    if(transaction.error.code != SKErrorPaymentCancelled) {
        
        [self filedWithErrorCode:IAP_FILEDCOED_BUYFILED error:nil];
        
    } else {
        
        [self filedWithErrorCode:IAP_FILEDCOED_USERCANCEL error:nil];
    }
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    
}


#pragma mark 获取交易成功后的购买凭证

- (void)getReceipt {

    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
   
    self.receipt = [receiptData base64EncodedStringWithOptions:0];
}




#pragma mark 错误信息反馈
- (void)filedWithErrorCode:(NSInteger)code error:(NSString *)error {
   
    if (self.delegate && [self.delegate respondsToSelector:@selector(filedWithErrorCode:andError:)]) {
        switch (code) {
            case IAP_FILEDCOED_APPLECODE:
                [self.delegate filedWithErrorCode:IAP_FILEDCOED_APPLECODE andError:error];
                break;

                case IAP_FILEDCOED_NORIGHT:
                [self.delegate filedWithErrorCode:IAP_FILEDCOED_NORIGHT andError:nil];
                break;

            case IAP_FILEDCOED_EMPTYGOODS:
                [self.delegate filedWithErrorCode:IAP_FILEDCOED_EMPTYGOODS andError:nil];
                break;

            case IAP_FILEDCOED_CANNOTGETINFORMATION:
                 [self.delegate filedWithErrorCode:IAP_FILEDCOED_CANNOTGETINFORMATION andError:nil];
                break;

            case IAP_FILEDCOED_BUYFILED:
                 [self.delegate filedWithErrorCode:IAP_FILEDCOED_BUYFILED andError:nil];
                break;

            case IAP_FILEDCOED_USERCANCEL:
                 [self.delegate filedWithErrorCode:IAP_FILEDCOED_USERCANCEL andError:nil];
                break;

            default:
                [self.delegate filedWithErrorCode:IAP_FILEDCOED_USERCANCEL andError:nil];
                break;
        }
    }
}



- (NSString *)getUuid{
    // create a new UUID which you own
    CFUUIDRef uuidref = CFUUIDCreate(kCFAllocatorDefault);
    
    // create a new CFStringRef (toll-free bridged to NSString)
    // that you own
    CFStringRef uuid = CFUUIDCreateString(kCFAllocatorDefault, uuidref);
    
    NSString *result = (__bridge NSString *)uuid;
    //release the uuidref
    CFRelease(uuidref);
    // release the UUID
    CFRelease(uuid);
    
    return result;
}

- (NSString *)chindDateFormate:(NSDate *)update{
   
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *destDateString = [dateFormatter stringFromDate:update];
    return destDateString;
}

//支付成功
-(void)paySuccessWithResult:(NSString *)result resultCode:(NSInteger)resultCode{
    
//    [self postLogWithParamWithEvent:@"launch_pay_resp" result:result resultCode:resultCode];
}
//数据打点
//-(void)postLogWithParamWithEvent:(NSString *)event result:(NSString *)result resultCode:(NSInteger)resultCode{
//    NSMutableArray *dataList = [NSMutableArray array];
//    NSDictionary *dict2 = @{
//        @"event":event,
//        @"code":self.productId ? self.productId : @"",
//        @"uuid":[UUIDStrengthen getDeviceIDInKeychain],
//        @"orderId":self.orderNo ? self.orderNo : @"",
//        @"durationTime":@"0",
//        @"elapsedTime":@"0",
//        @"result":result ? result : @"error",
//        @"resultCode":@(resultCode ? resultCode : 0),
//        @"tm" : @([ASTool gs_getCurrentTimeToMilliSecond])
//    };
//    [dataList addObject:dict2];
//    [[ASNetManager shareNetManager]postLogWithParam:dataList subtype:@"purchase_detail"];
//}
@end
